iT邦幫忙

2025 iThome 鐵人賽

DAY 23
0
Modern Web

每天一點 API:打造我的生活小工具系列 第 23

Day 23 — 練習用 POST 傳資料,讓 API 接收請求

  • 分享至 

  • xImage
  •  

昨天我們學了 API 中的標頭和快取運作原理。今天,我們要動手練習 POST 請求。

POST 請求是與 API 互動時很常見的一種操作,也是比較容易發生錯誤的地方。為了讓練習更安全、更簡單,我是用一個叫做 httpbin.org 的網站,這個網站是專門為開發者設計的測試環境。

使用 httpbin.org,我們可以把資料送出去,然後它會完整地回傳剛剛我們送出的資訊,讓我們清楚看到資料到底怎麼傳送的,方便理解和除錯。這樣我們就能更放心地練習 POST 請求,學會正確的用法。

今天的小專案目標

我今天的小專案目標是用 Python 的 requests 套件,向 httpbin.org 送出一個 POST 請求,把資料放在請求的正文(body)裡。我會傳送一份 JSON 格式的資料給伺服器,也會比較 JSON 和表單(form)兩種格式的差別,並加上自訂的標頭(headers)來模擬真實的 API,最後學習如何觀察回傳結果並處理錯誤。

什麼是 POST?

在 HTTP 裡,有幾種常見的方法用來和伺服器溝通,像是 GET、POST、PUT、DELETE。

POST 方法是用來把資料送給伺服器的。

舉例來說:

  • 送我們的帳號和密碼到網站做登入。

  • 把 JSON 格式的資料傳給 API 伺服器,讓它做分析或處理。

  • 上傳表單資料或檔案給伺服器。

POST 最特別的是,它會把資料放在請求的正文(body)裡面傳送,不像 GET 那樣把資料放在網址上,這樣更安全也可以傳送比較多、更複雜的資料。

實作流程

步驟 0:環境準備

pip install requests

步驟 1:練習一個 POST 的範例
建立一個叫 day23_post_httpbin.py 的檔案。

import requests, json

URL = "https://httpbin.org/post"

payload = {
    "user": "ariel",
    "task": "post-demo",
    "tags": ["http", "post", "json"]
}

r = requests.post(URL, json=payload, timeout=10)
r.raise_for_status()

data = r.json()
print("HTTP 狀態碼:", r.status_code)
print("伺服器看到的 Content-Type:", data["headers"]["Content-Type"])
print("伺服器回顯的 JSON:", json.dumps(data["json"], ensure_ascii=False))

步驟 2:比較 JSON 和表單格式
定義兩個函式,一個用 JSON 傳資料,另一個用表單傳資料。

def post_json():
    return requests.post(URL, json={"msg": "hello-json"}, timeout=10).json()

def post_form():
    return requests.post(URL, data={"msg": "hello-form"}, timeout=10).json()

print("—— JSON 版 ——")
j = post_json()
print("Content-Type:", j["headers"]["Content-Type"])
print("json 回顯   :", j["json"])
print("form 回顯   :", j["form"])

print("\n—— 表單版 ——")
f = post_form()
print("Content-Type:", f["headers"]["Content-Type"])
print("json 回顯   :", f["json"])
print("form 回顯   :", f["form"])

比較結果:

用 JSON 傳的資料會出現在回應的 json 部分。

用表單傳的資料會出現在回應的 form 部分。

Content-Type 標頭也不同,JSON 是 application/json,表單是 application/x-www-form-urlencoded

步驟 3:加上自訂標頭
我們可以自己定義標頭,例如加入授權的 Token。

headers = {
    "X-Demo": "day23",
    "Authorization": "Bearer FAKE_TOKEN_FOR_DEMO"
}
r = requests.post(URL, json={"demo": True}, headers=headers)
data = r.json()
print("伺服器看到的 Authorization:", data["headers"].get("Authorization"))
print("伺服器看到的 X-Demo      :", data["headers"].get("X-Demo"))

這樣能模擬真實情況下,API 需要帶 Token 或金鑰的請求。

步驟 4:練習錯誤處理
網路請求有時會失敗,比如伺服器回錯誤或網路斷線。我們可以加錯誤處理,讓程式不會直接當掉。

try:
    r = requests.post("https://httpbin.org/status/404", json={"x":1}, timeout=5)
    r.raise_for_status()
except requests.exceptions.HTTPError as e:
    print("HTTP 錯誤:", e)
except requests.exceptions.Timeout:
    print("連線逾時,請檢查網路。")
except requests.exceptions.RequestException as e:
    print("其他錯誤:", e)

這段程式能捕捉不同錯誤,像是 HTTP 錯誤、連線逾時等,幫助我們知道問題出在哪裡並且安全處理。

執行結果:

HTTP 狀態碼: 200
伺服器看到的 Content-Type: application/json
伺服器回顯的 JSON: {"tags": ["http", "post", "json"], "task": "post-demo", "user": "alice"}
—— JSON 版 ——
Content-Type: application/json
json 回顯   : {'msg': 'hello-json'}
form 回顯   : {}
—— 表單版 ——
Content-Type: application/x-www-form-urlencoded
json 回顯   : None
form 回顯   : {'msg': 'hello-form'}
伺服器看到的 Authorization: Bearer FAKE_TOKEN_FOR_DEMO
伺服器看到的 X-Demo      : day23
HTTP 錯誤: 404 Client Error: NOT FOUND for url: https://httpbin.org/status/404

接下來,我會簡單的解釋執行結果的內容。

HTTP 狀態碼:200
這是表示主要 POST 請求成功(OK)。代表伺服器接受並處理了我們的請求。

伺服器看到的 Content-Type:application/json
我們用的是 JSON 請求體。requests.post(..., json=payload) 會自動加上這個標頭並把資料序列化成 JSON。

伺服器回顯的 JSON:{"tags": [...], "task": "post-demo", "user": "alice"}
伺服器把我們送去的 JSON 原封不動回傳。證明 payload 有正確送達與被解析。

—— JSON 版 ——

Content-Type: application/json
這是確認 JSON 送法無誤。

json 回顯 : {'msg': 'hello-json'}
JSON 主體被伺服器解析成 JSON。

form 回顯 : {}
因為不是用表單送,所以伺服器的 form 區是空的。

—— 表單版 ——

Content-Type: application/x-www-form-urlencoded
這段是用 data=...(表單)送,Content-Type 就會是表單類型。

json 回顯 : None
不是 JSON body,所以解析不到 JSON。

form 回顯 : {'msg': 'hello-form'}
表單欄位成功被伺服器解析並回顯。

HTTP 錯誤:404 ... /status/404
這是刻意打的 404 測試端點,用來驗證錯誤處理。r.raise_for_status() 正常丟出 HTTPError,代表例外處理有生效,這不是我們的程式壞掉。

今日總結

今天我學會了如何用 Python 送出 POST 請求,了解 POST 是把資料放在請求的正文裡,不像 GET 是放在網址後面。我也知道了 JSON 和表單格式的差別,主要是在 Content-Type 標頭和資料格式上。透過使用 httpbin.org,我可以安全地測試標頭、正文和身份驗證,並觀察伺服器如何接收資料。這次練習讓我更清楚 API 互動的流程,也學會在發送資料前檢查格式和處理錯誤。


上一篇
Day 22 — HTTP 標頭、快取與 CORS 一次搞懂
系列文
每天一點 API:打造我的生活小工具23
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言